package com.dtp.core.thread;

import java.util.AbstractQueue;
import java.util.Collection;
import java.util.Iterator;
import java.util.Optional;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.TimeUnit;

/**
 * ExecutorAdapter继承Executor，这个接口的目标是尽可能与ThreadPoolExecutor兼容
 *
 * @author dragon-zhang
 * @since 1.1.3
 *
 * @remark muse
 **/
public interface ExecutorAdapter<E extends Executor> extends Executor {

    /** 获得原始执行器 */
    E getOriginal();

    /** 执行任务 */
    @Override
    default void execute(Runnable command) {
        getOriginal().execute(command);
    }

    /** 获得核心线程池大小 */
    int getCorePoolSize();

    /** 设置核心线程池大小 */
    void setCorePoolSize(int corePoolSize);

    /** 获得最大线程池大小 */
    int getMaximumPoolSize();

    /** 设置最大线程池大小 */
    void setMaximumPoolSize(int maximumPoolSize);

    /** 获得线程池大小 */
    int getPoolSize();

    /** 获得活跃线程数量 */
    int getActiveCount();

    /** 获得线程池的最大容量（默认不支持） */
    default int getLargestPoolSize() {return -1;}

    /** 获得任务数（默认不支持） */
    default long getTaskCount() {return -1;}

    /** 获得已完成的任务数量（默认不支持） */
    default long getCompletedTaskCount() {return -1;}

    /** 获得任务队列 */
    default BlockingQueue<Runnable> getQueue() {return new UnsupportedBlockingQueue();}

    /** 获得拒绝策略处理器（默认不支持） */
    default RejectedExecutionHandler getRejectedExecutionHandler() {return null;}

    /** 设置拒绝策略处理器（默认不支持）*/
    default void setRejectedExecutionHandler(RejectedExecutionHandler handler) {}

    /** 获得拒绝策略处理器名称 */
    default String getRejectHandlerName() {
        return Optional.ofNullable(getRejectedExecutionHandler())
                .map(h -> h.getClass().getSimpleName())
                .orElse("unsupported");
    }

    /** 是否允许核心线程超时（默认不支持）*/
    default boolean allowsCoreThreadTimeOut() {return false;}

    /** 设置是否允许核心线程超时（默认不支持）*/
    default void allowCoreThreadTimeOut(boolean value) {}

    /** 获得keep alive时间（默认不支持）*/
    default long getKeepAliveTime(TimeUnit unit) {return -1;}

    /** 设置keep alive时间 */
    default void setKeepAliveTime(long time, TimeUnit unit) {}

    /** 各种操作都不支持的阻塞队列 */
    class UnsupportedBlockingQueue extends AbstractQueue<Runnable> implements BlockingQueue<Runnable> {
        @Override
        public Iterator<Runnable> iterator() {throw new UnsupportedOperationException();}
        @Override
        public int size() {return 0;}
        @Override
        public void put(Runnable runnable) throws InterruptedException {throw new UnsupportedOperationException();}
        @Override
        public boolean offer(Runnable runnable, long timeout, TimeUnit unit) {throw new UnsupportedOperationException();}
        @Override
        public Runnable take() {throw new UnsupportedOperationException();}
        @Override
        public Runnable poll(long timeout, TimeUnit unit) {throw new UnsupportedOperationException();}
        @Override
        public int remainingCapacity() {return 0;}
        @Override
        public int drainTo(Collection<? super Runnable> c) {throw new UnsupportedOperationException();}
        @Override
        public int drainTo(Collection<? super Runnable> c, int maxElements) {throw new UnsupportedOperationException();}
        @Override
        public boolean offer(Runnable runnable) {throw new UnsupportedOperationException();}
        @Override
        public Runnable poll() {throw new UnsupportedOperationException();}
        @Override
        public Runnable peek() {throw new UnsupportedOperationException();}
    }
}
